/*
 * @(#)TriggerSubWorkflow.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.action;

import java.sql.Connection;
import java.sql.SQLException;

import org.quartz.JobDataMap;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.EventLogger;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.Utility;
import com.dcivision.workflow.WorkflowErrorConstant;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.core.WorkflowProcessor;
import com.dcivision.workflow.core.WorkflowProgressManager;
import com.dcivision.workflow.web.MaintWorkflowRecordForm;


/**
 * TriggerSubWorkflow.java
 *
 * Automatic task to trigger sub workflow
 *
 * @author           Nancy Zhang
 * @company          DCIVision Limited
 * @creation date    21/06/2005
 * @version          $Revision: 1.9.2.1 $
 */
public class TriggerSubWorkflow extends AbstractStartSubWorkflow {

    public TriggerSubWorkflow() {
        this.numOfRoutine = 1;
        this.labelType = WorkflowProcessor.LABEL_TYPE_USER_DEFINE;
        this.labelString = new String[] {"workflow.label.step_status_G"};
        this.parameterNames = new String[]{"workflow.label.workflow_code"};
        this.parentDependent = true;

        if (this.parentDependent) {
            this.currentProgressStatus = WorkflowProgress.STATUS_PENDING; //* subworkflow has close relationship with parent
        } else {
            this.currentProgressStatus = WorkflowProgress.STATUS_GENERAL_ACCOMPLISHMENT; //* subflow running independent of the parnet workflow
        }
    }

    public void execute(JobDataMap jobDataMap, WorkflowProgress currentProgress) throws ApplicationException {
        log.info("***** TriggerSubWorkflow workflow processor BEGIN *****");
        Connection conn = null;

        Integer triggerEventUserID = new Integer(0);
        String serverName = "127.0.0.1";
        String functionName = SystemFunctionConstant.WORKFLOW_TASK;
        String errorMessage = "";

        try {
            SessionContainer sessionCon = this.getSessionContainer();
            conn = this.getConnection();
            /*************************************************************
             *  get Event Log Information Begin
             *************************************************************/
            if (!Utility.isEmpty(sessionCon.getUserRecordID())) {
                triggerEventUserID = sessionCon.getUserRecordID();
            }

            if (!Utility.isEmpty(sessionCon.getUserIPAddress())) {
                serverName = sessionCon.getUserIPAddress();
            }
            errorMessage = "TriggerSubWorkflow.java -- Track ID: " + currentProgress.getTrackID() +
                     ", Workflow Progress ID : " + currentProgress.getID() +
                     ", Workflow Step ID: " + currentProgress.getWorkflowStepID() +
                     "<br> ";

            /*************************************************************
             *  get Event Log Information End
             *************************************************************/
            /* //for schedule job useing the processer connection.
            boolean isLocalConnection = false;
            if(!Utility.isEmpty(this.getConnection())){
                conn = this.getConnection();
            }else{
                isLocalConnection = true;
                conn = DataSourceFactory.getConnection();
            }

            // create required DAObject
            WorkflowRecordDAObject recordDAO = new WorkflowRecordDAObject(sessionCon, conn);
            WorkflowProgressManager progressManager = new WorkflowProgressManager(sessionCon, conn);
            MtmWorkflowChildParentProgressDAObject subworkflowDAO = new MtmWorkflowChildParentProgressDAObject(sessionCon, conn);

            log.info("current progress' workflow step id: "+currentProgress.getWorkflowStepID());
            Integer userRecordID = currentProgress.getUpdaterID();
            UserRecordDAObject userDAO = new UserRecordDAObject(sessionCon, conn);
            log.info("userRecordID: "+userRecordID);
            UserRecord userRecord = (UserRecord) userDAO.getObjectByID(userRecordID);
            sessionCon.setUserRecord(userRecord);

      // ------------------------------------------------------------Get sub workflow record.

            WorkflowStepParameterValueDAObject paraDAO=new WorkflowStepParameterValueDAObject(sessionCon, conn);
            List tempList=paraDAO.getListByStepID(currentProgress.getWorkflowStepID());
            Integer subWorkflowRecordID = null;
            if(!Utility.isEmpty(tempList)){
                for (int i = 0; i < tempList.size(); i++) {
                    WorkflowStepParameterValue stepParameterValue = (WorkflowStepParameterValue)tempList.get(i);
                    if (WorkflowRetrievalManager.PARAMVALUE_SUB_WORKFLOW.equals(stepParameterValue.getParameterType())) {
                        WorkflowRecord workflowRecord=(WorkflowRecord) recordDAO.getEffectiveWorkflowRecordByWorkflowCode(stepParameterValue.getParameterValue());
                        if (!Utility.isEmpty(workflowRecord)) {
                            log.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>"+workflowRecord.getID());
                            subWorkflowRecordID = workflowRecord.getID();
                            break;
                        }
                    }
                }
            }

            // ----------------------------------------------------------Trigger sub workflow.

            WorkflowRecord workflowRecord = (WorkflowRecord) recordDAO.getObjectByID(subWorkflowRecordID);
            MaintWorkflowRecordForm recordForm = new MaintWorkflowRecordForm();
            recordForm.setFormData(workflowRecord);
            Integer autoUserID=progressManager.getAutoTaskActorUser(currentProgress);
            log.debug("start workflow start new track");
            WorkflowProgress workflowProgress = (WorkflowProgress) progressManager.startWorkflowTrack(recordForm,autoUserID);
            log.debug("end workflow start new track");


            if (this.parentDependent) {
                log.debug("add workflow child parent progress record");
                MtmWorkflowChildParentProgress childWorkflowParentProgress = new MtmWorkflowChildParentProgress();
                childWorkflowParentProgress.setParentWorkflowProgressID(currentProgress.getID());
                childWorkflowParentProgress.setSubworkflowTrackID(workflowProgress.getTrackID());
                childWorkflowParentProgress = (MtmWorkflowChildParentProgress) subworkflowDAO.insertObject(childWorkflowParentProgress);
                log.debug("finish add workflow child parent progress record");
            }

            //* after the execution, set the desired appropriate out number
            //this.returnRoutineIndex = 1; //* should be between 0 and numOfRoutine-1
            //* if need to auto-Execute the following step, set the below variable to true (default false)
            this.bAutoExecuteNextStep=false;
            this.bCreateNextWorkflowProgress=true;

            if(isLocalConnection){
                conn.commit();
            }*/

            //create the DAO--------------
            WorkflowProgressManager progressManager = new WorkflowProgressManager(sessionCon, conn);

            //get the subWorkflowRecord
            WorkflowRecord workflowRecord = this.getSubWorkflowRecord(sessionCon, conn, currentProgress.getWorkflowStepID());

            //set the Form
            MaintWorkflowRecordForm recordForm = new MaintWorkflowRecordForm();
            recordForm.setFormData(workflowRecord);

            //set the sessionContainer info
            setSessionContainer(sessionCon,conn,currentProgress);

            //start the subWorkflow--------------
            log.debug("start workflow start new track");
            Integer autoUserID=progressManager.getAutoTaskActorUser(currentProgress);
            if(Utility.isEmpty(autoUserID)){
                autoUserID = currentProgress.getUpdaterID();//if autoUserID is null,startSubWorkflow will throw exception
            }
            WorkflowProgress workflowProgress = (WorkflowProgress) progressManager.startWorkflowTrack(recordForm,autoUserID);
            log.debug("end workflow start new track");
            //-start subworkflow end---

            //set child-parent progress ship--
            setChildParentProgressShip(sessionCon,conn,currentProgress,workflowProgress);

            this.bAutoExecuteNextStep=false;
            this.bCreateNextWorkflowProgress=true;
            this.commitConnection(conn);

        } catch (ApplicationException appEx) {
            log.error("Application exception:\n", appEx);
            /***********************************
             *  Record the Event Log.
             ***********************************/
            EventLogger.logEventMessage(triggerEventUserID, serverName, errorMessage, appEx.getMsgCode(), WorkflowErrorConstant.LOG_AUTO_TASK_ERROR_CODE, functionName, appEx.toString() );
            try {
                this.rollbackConnection(conn);
            } catch (SQLException rollbackE) {}
            throw appEx; //* prop
        } catch (Exception e) {
            log.error("Error during processing this automatic task.", e);
            /***********************************
            *  Record the Event Log.
            ***********************************/
            EventLogger.logEventMessage(triggerEventUserID, serverName, errorMessage, ErrorConstant.COMMON_FATAL_ERROR, WorkflowErrorConstant.LOG_AUTO_TASK_ERROR_CODE, functionName, e.toString() );
            try {
                this.rollbackConnection(conn);
            } catch (SQLException rollbackE) {}
            throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR); //* throw an applicationExcpetion with an appropriate
        } finally {
            if(isLocalConnection){
                try { conn.close(); } catch (Exception ignore) {} finally { conn = null; }
            }
        }
        log.info("***** TriggerSubWorkflow workflow processor END   *****");
    }

    public static void main(String[] args) {
    }
}
